package cn.ljy.authority.service.impl;

import cn.ljy.authority.dao.mapper.SysDepartmentMapper;
import cn.ljy.authority.dao.mapper.SysUserMapper;
import cn.ljy.authority.model.SysDepartment;
import cn.ljy.authority.model.query.SysDepartmentQuery;
import cn.ljy.authority.model.query.SysUserQuery;
import cn.ljy.authority.service.SysDepartmentService;
import cn.ljy.authority.utils.MyObjectUtils;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.common.exception.model.MyWebException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Service
@Validated
@Slf4j
public class ISysDepartmentService extends IBaseService<SysDepartment, SysDepartmentQuery> implements SysDepartmentService {

    @Autowired
    private SysDepartmentMapper mapper;
    @Autowired
    private SysUserMapper sysUserMapper;


    /**
     * 设置关联属性
     * @param department
     */
    private void setParam(SysDepartment department){
        //添加相关关联属性
        //部门下的员工数
        SysUserQuery sysUserQuery=new SysUserQuery();
        sysUserQuery.setDepartment(department);
        department.setUserNumber(sysUserMapper.count(sysUserQuery));
    }

    /**
     * 采用非递归形式，为树形集合设置关联属性
     * 说明：
     * 1.应该是树形结构，即每个点应该都带children
     * 2.如果不是树形结构（例如直接查询集合列表），则children不应该带值，否则会严重影响效率
     * @param tree
     */
    private void setTreeDepartmentParam(List<SysDepartment> tree){
        tree.stream().forEach(department -> {
            //添加相关关联属性
            setParam(department);
            List<SysDepartment> childrens=department.getChildren();
            List<SysDepartment> childrensTmp=new ArrayList<>();//临时存储对象
            while(childrens.size()>0){
                for(SysDepartment departmentChildren:childrens){
                    //添加相关关联属性
                    setParam(departmentChildren);
                    childrensTmp.addAll(departmentChildren.getChildren());
                }
                //遍历结束后
                childrens=new ArrayList<>();//清空集合，不用用clear，否则会把原集合的引用对象移除
                childrens.addAll(childrensTmp);//重置children集合
                childrensTmp=new ArrayList<>();//清空临时集合，不能用clear，需要重新更换地址
            }
        });
    }

    @Override
    protected void beforeGet(Serializable id) {

    }

    @Override
    protected void beforeUpdate(SysDepartment sysDepartment) {
        if(sysDepartment.getId()==null){
            throw new MyWebException("编辑失败：标识符不能为空");
        }
        if(sysDepartment.getId().equals(sysDepartment.getParentId())){
            throw new MyServiceException("编辑失败：不能选择自己作为上级部门");
        }
    }

    @Override
    protected void beforeSave(SysDepartment sysDepartment) {

    }

    @Override
    protected void beforeDelete(Serializable[] ids) {
        for(Serializable id:ids){
            //判断是否有子部门信息
            SysDepartmentQuery sysDepartmentQuery=new SysDepartmentQuery();
            sysDepartmentQuery.setParentId(Long.valueOf(id.toString()));
            if(mapper.count(sysDepartmentQuery)>0){//如果还有子部门
                throw new MyServiceException("删除失败：请先删除子部门信息");
            }
            //判断该部门下是否有账户信息
            SysUserQuery sysUserQuery=new SysUserQuery();
            sysUserQuery.setDepartment(new SysDepartment(Long.valueOf(id.toString())));
            if(sysUserMapper.count(sysUserQuery)>0){
                throw new MyServiceException("删除失败：请先转移或移除该部门下的员工信息");
            }
        }
    }

    @Override
    protected void beforeForceDelete(Serializable[] ids) {
        for(Serializable id:ids){
            //判断该部门下是否有账户信息。存在账户信息不能强制删除
            SysUserQuery sysUserQuery=new SysUserQuery();
            sysUserQuery.setDepartment(new SysDepartment(Long.valueOf(id.toString())));
            if(sysUserMapper.count(sysUserQuery)>0){
                throw new MyServiceException("删除失败：请先转移或移除该部门下的员工信息");
            }
            //判断是否有子部门信息
            SysDepartmentQuery sysDepartmentQuery=new SysDepartmentQuery();
            sysDepartmentQuery.setParentId(Long.valueOf(id.toString()));
            if(mapper.count(sysDepartmentQuery)>0){//如果还有子部门
                throw new MyServiceException("删除失败：请先删除子部门信息");
            }

        }
    }

    @Override
    public List<SysDepartment> findTree(SysDepartmentQuery sysDepartmentQuery) {
        List<SysDepartment> tree=new ArrayList();
        if(MyObjectUtils.checkObjAllFieldsIsNull((sysDepartmentQuery))){//如果
            tree=mapper.findTree();
        }else{
            tree = mapper.findAll(sysDepartmentQuery);
        }
        //设置关联属性
        setTreeDepartmentParam(tree);
        return tree;
    }

    private List<SysDepartment> buildTree(List<SysDepartment> list){
        List<SysDepartment> tree=new ArrayList();
        for(SysDepartment sysDepartment:list){
            if(tree.size()==0){//如果是第一次添加
                tree.add(sysDepartment);
                break;
            }
            for(SysDepartment department:tree){
                if(department.getParentId().equals(sysDepartment.getId())){
                }
            }

        }
        return tree;
    }



}
